#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSettings>
#include <QLabel>
#include <QToolButton>
#include <QTreeWidgetItem>

#include "commondef.h"
#include "database.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:

    void onTabCloseRequested(int index);

    void onAddNewConnectionMysql();

    void onAddNewConnectionSqlServer();

    void onAddNewConnectionAccess();

    void onAddNewConnectionSqlite();

    void onAddNewConnection();

    void onTreeItemDoubleClicked(QTreeWidgetItem * item, int column);

    void onCustomContextMenuRequested(const QPoint &pos);

    void onModifyConnectionTriggered();

    void onOpenConnectionTriggered();

private:

    // 连接信号槽
    void initSignalSlots();

    // 初始化连接列表
    void initTreeWidget();

    // 初始化底部状态栏
    void initStatusBar();

    /**
     * @brief loadConnections 加载一个数据库类型的所有连接信息
     * @param type 数据库类型
     */
    void loadConnections(DataBaseType type);

    /**
     * @brief newConnection 新增一条连接信息
     * @param type 数据库类型
     */
    void newConnection(DataBaseType type);

    /**
     * @brief saveConnectionInfo 保存连接信息
     * @param info 连接信息
     * @param type 数据库类型
     * @param isNew 是否是新增数据
     * @return 成功返回true
     */
    bool saveConnectionInfo(const MSS&info, DataBaseType type, bool isNew = true);

    /**
     * @brief addConnectionNode 添加连接节点
     * @param type 数据库类型
     * @param connection 连接名
     */
    void addConnectionNode(DataBaseType type, const QString &connection);

    /**
     * @brief isRepeatConnection 连接名是否已经存在
     * @param connectionName 连接名
     * @return 存在返回true
     */
    bool isRepeatConnection(const QString& connectionName);

    /**
     * @brief getTreeNode 获取节点下特定文本的子节点
     * @param item 父节点
     * @param text 子节点文本
     * @return 存在返回子节点
     */
    QTreeWidgetItem *getTreeNode(QTreeWidgetItem * item, const QString& text);

    /**
     * @brief getConnectionInfo 根据连接名和数据库类型获取连接信息
     * @param type 数据库类型
     * @param connection 连接名
     * @param info 连接信息
     * @return 返回连接在配置文件的索引
     */
    int getConnectionInfo(DataBaseType type, const QString& connection, MSS& info);

    /**
     * @brief getExistDbNum 获取一个数据库类型已添加的连接数
     * @param type 数据库类型
     * @return 已添加的连接数
     */
    int getExistDbNum(DataBaseType type);

    /**
     * @brief connectionDoubleClicked 双击连接节点
     * @param item 节点
     * @param column 列索引
     * @return 成功返回true
     */
    bool connectionDoubleClicked(QTreeWidgetItem * item, int column);

    /**
     * @brief databaseDoubleClicked 双击数据库节点
     * @param item 节点
     * @param column 列索引
     * @return 成功返回true
     */
    bool databaseDoubleClicked(QTreeWidgetItem * item, int column);

    /**
     * @brief tableDoubleClicked 双击数据表节点
     * @param item 节点
     * @param column 列索引
     * @return 成功返回true
     */
    bool tableDoubleClicked(QTreeWidgetItem * item, int column);

    /**
     * @brief openConnection 打开连接
     * @param db 连接数据库对象
     * @param connection 连接名
     * @param type 数据库类型
     * @return 成功返回true
     */
    bool openConnection(Database* db, const QString& connection, DataBaseType type, QString& dbName);

    /**
     * @brief addTreeNode 添加树子节点
     * @param parent 父节点
     * @param iconPath 节点图标路径
     * @param text 节点标签文本
     * @param type 节点类型
     * @return 成功返回true
     */
    bool addTreeNode(QTreeWidgetItem* parent, const QString& iconPath, const QString& text, TreeNodeType type);

    void addTableNodes(QTreeWidgetItem* parent, Database*db, DataBaseType type);

private:
    Ui::MainWindow *ui;
    QSettings *m_settings;
    QMap<QString, QMap<QString, Database*>> m_openConnections;// 已打开的连接

    // 状态栏控件
    QLabel *m_labelSql;// 执行的sql
    QLabel *m_labelExeTime;// 执行sql耗时
    QLabel *m_labelDataNum;// 查数据条数信息
    QToolButton *m_toolButtonShowLeft;// 显影左侧列表
    QToolButton *m_toolButtonShowRight;// 显隐右侧列表
    QToolButton *m_toolButtonShowList;// 显示列表
    QToolButton *m_toolButtonShowDetail;// 显示详细信息
    QToolButton *m_toolButtonShowEr;// 显示ER图
};
#endif // MAINWINDOW_H
